package com.panopset.sf;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.TransferHandler;

import com.panopset.Logger;
import com.panopset.compat.Strings;
import com.panopset.io.Filez;
import com.panopset.nls.MsgProps;

public class PanFile extends PanField {
	
	private final JFrame parent;
	private MnemonicGroup mg;
	public MnemonicGroup getMnemonicGroup() {
		if (mg == null) {
			mg = new MnemonicGroup();
		}
		return mg;
	}
	public void setMnemonicGroup(MnemonicGroup mnemonicGroup) {
		if (mg != null) {
			throw new RuntimeException("Call this method prior to getPanel()");
		}
		mg = mnemonicGroup;
	}
	
	public File getFile() {
		return new File(getTF().getText());
	}

	public void setSelectedFile(File file) {
		getTF().setText(new Filez().getCanonicalPath(file));
	}

	public PanFile(Windoc swingDoc, String title, String defaultPath) {
		super(swingDoc, title, defaultPath);
		parent = swingDoc.getFrame();
	}

	@Override
	protected void populatePanel(final JPanel panel) {
		panel.setLayout(new GridBagLayout());
		JButton btn = new JButton(
				new MsgProps(Windoc.SD_MSG_PROPS).get("browse"));
		btn.setMnemonic(getMnemonicGroup().findMnemonic(btn));
		btn.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				doNew();
			}
		});
		FontManager.getInstance().register(btn, FontManager.FontType.boldArial);
		final GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		panel.add(btn, gbc);
		gbc.gridx++;
		panel.add(getDropper(), gbc);
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.gridx++;
		gbc.weightx = 1.0;
		panel.add(getTF(), gbc);
	}

	private void doNew() {
		JFileChooser chooser = new JFileChooser();
		String s = getTF().getText();
		if (Strings.isPopulated(s)) {
			chooser.setSelectedFile(new File(s));
		}
		chooser.setFileSelectionMode(fsm);
		chooser.setDialogTitle(title);
		chooser.setDialogType(jdt);
		if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
			setSelectedFile(chooser.getSelectedFile());
		}
	}

	private int fsm = JFileChooser.FILES_AND_DIRECTORIES;
	private int jdt = JFileChooser.OPEN_DIALOG;

	/**
	 * 
	 * @param value
	 *            Default is JFileChooser.OPEN_DIALOG.
	 */
	public void setDialogType(final int value) {
		jdt = value;
	}

	/**
	 * 
	 * @param value
	 *            Default is JFileChooser.FILES_AND_DIRECTORIES.
	 */
	public void setFileSelectionMode(final int value) {
		fsm = value;
	}

	/**
	 * dropper.
	 */
	private JTextField dropper;

	/**
	 * @return Dropper.
	 */
	private JTextField getDropper() {
		if (dropper == null) {
			dropper = new JTextField(2);
			dropper.setEditable(false);
			dropper.setText(">>");
			dropper.setToolTipText(new MsgProps(Windoc.SD_MSG_PROPS)
					.get("drgndrp")
					+ " "
					+ new MsgProps(Windoc.SD_MSG_PROPS).get("file")
					+ " "
					+ new MsgProps(Windoc.SD_MSG_PROPS).get("here"));
			dropper.setBackground(Color.CYAN);
			dropper.setDragEnabled(true);
			dropper.setTransferHandler(new FileDropHandler());
		}
		return dropper;
	}

	/**
	 * File drop handler.
	 * 
	 * Reference:
	 * 
	 * http://weblogs.java.net/blog/shan_man/archive/2006/09/toplevel_drop_w.
	 * html
	 * 
	 */
	final class FileDropHandler extends TransferHandler {

		/**
		 * 1L.
		 */
		private static final long serialVersionUID = 1L;

		/**
		 * Can import.
		 * 
		 * @param supp
		 *            Transfer support.
		 * @return True if the type of drag and drop is a list of files.
		 */
		public boolean canImport(final TransferSupport supp) {
			/* for the demo, we'll only support drops (not clipboard paste) */
			if (!supp.isDrop()) {
				return false;
			}

			/* return true if and only if the drop contains a list of files */
			return supp.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
		}

		/**
		 * Import data.
		 * 
		 * @param supp
		 *            Transfer support.
		 * @return True if successful.
		 */
		public boolean importData(final TransferSupport supp) {
			if (!canImport(supp)) {
				return false;
			}

			/* fetch the Transferable */
			Transferable t = supp.getTransferable();

			try {
				Object data = t.getTransferData(DataFlavor.javaFileListFlavor);
				if (!(data instanceof java.util.List<?>)) {
					return false;
				}
				java.util.List<?> objList = (java.util.List<?>) data;
				for (Object o : objList) {
					if (o instanceof File) {
						File file = (File) o;
						PanFile.this.setSelectedFile(file);
						return true;
					}
				}
			} catch (Exception e) {
				Logger.log(e);
			}
			return false;
		}
	}
}
